#include "MegaSprite.h"

#include "Game.h"

bool CMegaSprite::load(String sTextureName, int iTileWidth, int iTileHeight)
{
    
    m_iTileWidth = iTileWidth;
    m_iTileHeight = iTileHeight;
    
    Texture texture;
    
    //Load pixel data of whole image file
    unsigned char* cpData = CGame::getInstance()->getTextureHandler()->loadRawImageData(sTextureName.c_str(), texture);
    
    m_iWidth = texture.iWidth;
    m_iHeight = texture.iHeight;
    
    int iTileCountX = m_iWidth / m_iTileWidth;
    int iTileCountY = m_iHeight / m_iTileHeight;
    
    int iColors = texture.iBitDepth / 8;
    
    std::cout << iTileCountX << std::endl;
    std::cout << iTileCountY << std::endl;
    std::cout << m_iWidth << std::endl;
    std::cout << m_iHeight << std::endl;
    
    if (m_iWidth % m_iTileWidth != 0 || m_iHeight % m_iTileHeight != 0) {
        
        std::cout << "Error, MegaSprite image file dimensions (" << m_iWidth << "x" << m_iHeight << ") are not a multiple of the tile dimensions (" << m_iTileWidth << "x" << m_iTileHeight << "). Aborting MegaSprite load." << std::endl;
        return false;
        
    }
    
    std::cout << "Total size   = " << m_iWidth * m_iHeight * texture.iBitDepth/8 << std::endl;
    std::cout << "Biggest size = " << (m_iWidth-m_iTileWidth + m_iTileWidth-1 + (m_iHeight-m_iTileHeight + m_iTileHeight-1)*m_iWidth)*iColors << std::endl;
    
    //&cpData[(0 + 0/*y*m_iWidth * texture.iBitDepth/8*/) * texture.iBitDepth/8]
    
    //std::cout << (long)cpData[m_iWidth*m_iHeight*4] << std::endl;
    //std::cout << m_iWidth * m_iHeight * texture.iBitDepth/8 << ", Actual size = " << x*texture.iBitDepth/8 + (y)*m_iWidth * texture.iBitDepth/8 << std::endl;
    
    //Allocate a memory buffer for the new tiles
    unsigned char* cpTileData = new unsigned char[m_iTileWidth*m_iTileHeight*iColors];
    
    //Iterate through each tile of data
    for (int TileX=0;TileX<m_iWidth;TileX+=iTileWidth) {
        for (int TileY=0;TileY<m_iHeight;TileY+=iTileHeight) {
            
            //Iterate through the pixels in the tile
            for (int x=0;x<m_iTileWidth;++x) {
                for (int y=0;y<m_iTileHeight;++y) {
                    
                    //Iterate through the colors
                    for (int c=0;c<iColors;++c) {
                        
                        //Copy the data into the tile data array
                        cpTileData[(x + y*m_iTileWidth)*iColors + c] = cpData[(TileX + x + (TileY + y)*m_iWidth)*iColors + c];
                        
                    }
                    
                }
            }
            
            //Create a new texture from the tile data and add it to the array of tile textures
            m_iTileTextures.push_back( CGame::getInstance()->getTextureHandler()->
                genOpenGLTexture(cpTileData, m_iTileWidth, m_iTileHeight, texture.iBitDepth) );
            
        }
    }
    
    //We don't need the tile data any more
    delete [] cpTileData;
    
    //We don't need the image data any more
    delete [] cpData;
    
    //TODO: Remove this hack, replace with proper file loading
    m_vCenter = Vector(m_iWidth/2.f, m_iHeight/2.f);
    
}

void CMegaSprite::render()
{
    
    //Only apply transformations within this scope
    glPushMatrix();
    
    //Center the megasprite
    glTranslatef(-m_vCenter[0], -m_vCenter[1], 0);
    
    //Scale to individual tiles
    glScalef(m_iTileWidth, m_iTileHeight, 1.f);
    
    int iTileCountX = m_iWidth/m_iTileWidth;
    int iTileCountY = m_iHeight/m_iTileHeight;
    
    glColor4f(1, 1, 1, 1);
    
    for (int x=0;x<iTileCountX;++x) {
        for (int y=0;y<iTileCountY;++y) {
            
            //Bind the tile's texture
            glBindTexture(GL_TEXTURE_2D, m_iTileTextures[y + x*iTileCountY]);
            
            glBegin(GL_QUADS);
                
                glTexCoord2f(0.f, 0.f);
                glVertex3f(0.f, 0.f, 0.f);
                glTexCoord2f(1.f, 0.f);
                glVertex3f(1.f, 0.f, 0.f);
                glTexCoord2f(1.f, 1.f);
                glVertex3f(1.f, 1.f, 0.f);
                glTexCoord2f(0.f, 1.f);
                glVertex3f(0.f, 1.f, 0.f);
                
            glEnd();
            
            //Position the tile
            glTranslatef(0, 1, 0);
            
        }
        glTranslatef(0, -iTileCountY, 0);
        glTranslatef(1, 0, 0);
    }
    
    glPopMatrix();
    
}
